<?

/** Generic math function.
 *
 *  This collection of functions (libary) is licensed under GPL2.
 *  See LICENSE or www.gnu.org for more details.
 *  @author Jyry Kuukkanen
 *  @copyright Jyry Kuukkanen
 */


/** Rounds specified value to given precision
 *  Replaces php's native round() function. This uses an extra parameter, so
 *  that the last digit can be rounded to 5 as well as to 0. See examples
 *  below.
 *  Example:  e.g. soRound(3.47, 2, 2) -> 3.45
 *  Example:  e.g. soRound(3.477, 2, 2) -> 3.5
 *  Example:  if $Div is 1 the round works like normal round
 *
 *  @param float $InValue Value to round
 *  @param int $Decimals Number of decimals to round up to.
 *  @param int $Div number of segments the last number is divided into. The
 *  rounded value is always at the edge of a segment. See examples for more.
 *  @package somath
 */
function soRound($InValue, $Decimals = 0, $Div = 1) {
    if ($InValue == 0) return 0;
    if ($Div == 1) $Decimals++;
    
    $sign = $InValue / abs($InValue);
    $value = abs($InValue) * pow(10, $Decimals);
    $seg = floor(10 / $Div);
    $modulo = $value % $seg;
    $limit = $seg / 2;
    $fract = $value - floor($value);
    if (($modulo+$fract) < $limit)
        /* round down */
        $value = floor($value) - $modulo;
    else
        /* round up */
        $value = floor($value) + $seg - $modulo;
        
    return $sign * ($value / pow(10, $Decimals));
}; // soRound


/** Returns the sum of all elements in an array
 *  @param array/any $InArray Array of numbers
 *  @param bool $StrToNough When set, converts all non-numeric values to 0.
 *  @return dec/NULL Returns the sum or NULL on invalid array values
 *  @package somath
 */
function soSum($InArray, $StrToNough = 0) {
    $result = 0;
    $error = 0;
    $i = count($InArray);
    while ((--$i >= 0) && (!$error)) {
        $value = $InArray[$i];
        $numeric = soIsNum($value);
        if (!$numeric) {
            if ($StrToNough) {
                $value = 0;
            } else {
                $error = 1;
            }; // if $StrToNough
        }; // if $numeric

        if (!$error) $result += $value;
    }; // foreach

    if ($error) $result = NULL;

    return $result;
}; // soNum


/** Returns the average of all elements in an array
 *  @param array/any $InArray Array of numbers
 *  @return dec/NULL Returns the sum or NULL on invalid array values
 *  @package somath
 */
function soAvg($InArray) {
    $result = soSum($InArray);
    if (soIsNumm($result)) return NULL; // <-- EXIT

    $icount = count($InArray);
    return $result /$icount;
}; // soAvg

?>